package com.llt.ai.config;

import com.alibaba.cloud.ai.advisor.RetrievalRerankAdvisor;
import com.alibaba.cloud.ai.dashscope.chat.DashScopeChatModel;
import com.alibaba.cloud.ai.dashscope.rerank.DashScopeRerankModel;
import com.llt.ai.tools.BookingTools;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.chat.client.advisor.PromptChatMemoryAdvisor;
import org.springframework.ai.chat.client.advisor.SimpleLoggerAdvisor;
import org.springframework.ai.chat.memory.ChatMemory;
import org.springframework.ai.tool.ToolCallbackProvider;
import org.springframework.ai.vectorstore.SearchRequest;
import org.springframework.ai.vectorstore.VectorStore;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * 配置 ChatClient 所需的各种组件（向量搜索、记忆、工具等）
 * @Author: llt
 * @Date: 2025/7/31 22:58
 */
@Configuration
public class ChatClientConfig {

    /**
     * 配置检索增强重排序 Advisor，用于基于向量搜索+大模型重排序的 RAG 检索
     */
    @Bean
    public RetrievalRerankAdvisor retrievalRerankAdvisor(VectorStore vectorStore, DashScopeRerankModel dashScopeRerankModel) {
        return new RetrievalRerankAdvisor(vectorStore, dashScopeRerankModel, SearchRequest.builder().topK(5).build());
    }

    /**
     * 配置对话记忆 Advisor，可自动将历史对话上下文注入提示词中
     */
    @Bean
    public PromptChatMemoryAdvisor promptChatMemoryAdvisor(ChatMemory chatMemory) {
        return PromptChatMemoryAdvisor.builder(chatMemory).build();
    }

    /**
     * 核心 ChatClient Bean，配置默认模型、系统提示词、记忆、RAG 重排序、工具等
     */
    @Bean
    public ChatClient chatClient(DashScopeChatModel model, PromptChatMemoryAdvisor promptChatMemoryAdvisor, BookingTools bookingTools,
                                 ToolCallbackProvider toolCallbackProvider, RetrievalRerankAdvisor retrievalRerankAdvisor) {
        return ChatClient.builder(model)
                .defaultSystem("""
						##角色
                          您是“Lilt”航空公司的客户聊天支持代理。请以友好、乐于助人且愉快的方式来回复。
                          您正在通过在线聊天系统与客户互动。
                        ##要求
                          1.在涉及增删改（除了查询）function-call前，必须等用户回复“确认”后再调用tool。
                          2.请讲中文。
                          今天的日期是 {current_date}.
					""")
                // 开启记忆与向量化并打印日志
                .defaultAdvisors(retrievalRerankAdvisor, promptChatMemoryAdvisor, new SimpleLoggerAdvisor())
                // 自己的工具
                .defaultTools(bookingTools)
                // 外部的工具
                .defaultToolCallbacks(toolCallbackProvider)
                .build();
    }
}
